Skip to content

Add free trial email drip sequence templates#4

Open
sidneyswift wants to merge 2 commits intomainfrom
feature/trial-email-sequence
Open

Add free trial email drip sequence templates#4
sidneyswift wants to merge 2 commits intomainfrom
feature/trial-email-sequence

Conversation

@sidneyswift
Copy link
Copy Markdown
Contributor

@sidneyswift sidneyswift commented Mar 30, 2026

Summary

  • Adds content/email/ with plain-text email templates for the 30-day free trial onboarding drip sequence
  • 4 emails written (welcome, getting started, personalized follow-up, developer path) plus a sequence overview with timing and principles
  • Updates AGENTS.md with email drip section so agents understand what these files are and aren't

Test plan

  • Review email copy for tone and accuracy
  • Verify AGENTS.md changes are clear
  • Confirm pnpm build still passes (no code changes)

Made with Cursor

Summary by CodeRabbit

  • Documentation
    • Added a comprehensive 30-day free-trial email sequence with welcome, getting-started, developer, and follow-up templates plus sequence rules.
  • New Features
    • New marketing/design preview pages and hero variants for evaluation.
    • New homepage sections: marquee, live ingest feed, split proof, and system/status visuals.
    • New animated UI components: mock Agent chat, terminal feed, system diagram, marquee ticker, and figure labels.
  • UI / UX
    • Global styling updates, refreshed colors/typography, CTA/button restyles, and dark theme set as default.

Plain-text email copy for the 30-day trial onboarding sequence:
- Day 0: casual founder welcome
- Day 2: 3 ways to get started (onboard, research, email agent)
- Day 5: personalized follow-up with company research
- Day 8: developer path (API key, Claude/Cursor)

Includes sequence overview with timing, principles, and TODOs
for remaining emails. Updated AGENTS.md with email section.

Made-with: Cursor
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 30, 2026

📝 Walkthrough

Walkthrough

Adds a free-trial email drip template set and workspace guidance, extensive agent-browser documentation and templates, many new marketing/design pages and UI components, global CSS/theme changes, copy/nav updates, and a large set of UX-audit documents — all documentation and frontend/UI-focused changes across the repo.

Changes

Cohort / File(s) Summary
Email templates & workspace docs
AGENTS.md, content/email/sequence-overview.md, content/email/free-trial-welcome.md, content/email/getting-started.md, content/email/personalized-followup.md, content/email/developer-path.md
Added content/email/ templates and updated AGENTS.md with an "Email Drip Sequence" section. Introduces metadata, subject/body templates, design decisions, and automation guidance (templates as source-of-truth; workflows live in workflows/).
Agent-browser docs, refs & templates
.agents/skills/agent-browser/SKILL.md, .agents/skills/agent-browser/references/*, .agents/skills/agent-browser/templates/*, skills/agent-browser, skills-lock.json, .claude/skills/agent-browser
New comprehensive agent-browser documentation (commands, auth, session, refs, profiling, proxy, video, profiling), multiple Bash template scripts (capture, form automation, authenticated session), and skill pointer/lock files. Documentation-only additions and example automation scripts.
UX audit / design notes
.local/ux-audit/*, swipe/swipe-files/design-analysis.md, content/brand/website-copy-bank.md
Added a large collection of UX audit artifacts, iteration logs, prioritized improvements, user stories, teardown and rebuild direction docs, and a website copy bank / design analysis reference.
New marketing/design pages
apps/web/app/designs/a/page.tsx, .../designs/b/page.tsx, .../designs/c/page.tsx, .../designs/d/page.tsx, .../designs/e/page.tsx
Introduced five new static Next.js design/marketing pages with fixed layouts, inline font imports/styles and hero examples.
Homepage, pages, layout & global styles
apps/web/app/page.tsx, apps/web/app/layout.tsx, apps/web/app/globals.css, apps/web/app/company/about/page.tsx, apps/web/app/company/recoupable-records/page.tsx, apps/web/app/platform/page.tsx, apps/web/app/solutions/page.tsx, apps/web/app/developers/page.tsx, apps/web/app/*
Major homepage and page structure changes: new sections (Marquee, IngestFeed, split proof), theme initialization change (default dark), large globals.css overhaul (fonts, theme variables, utilities, animations), and multiple page layout restructures.
New UI components & client behavior
apps/web/components/home/* (AgentChat.tsx, IngestFeed.tsx, Marquee.tsx, StatusBar.tsx, SystemDiagram.tsx, Terminal.tsx, VisionOverlay.tsx), apps/web/components/ui/* (FigureLabel.tsx, SubscribeForm.tsx), apps/web/components/layout/* (Header.tsx, Footer.tsx, NavDropdown.tsx, ViewModeBar.tsx)
Added several new server/client React components (animated mockups, live-feeds, terminal, system diagram, marquee, status bar, vision overlay) and small UI tweaks (CTA styling, footer copy, nav dropdown empty-items handling, hiding ViewModeBar). Some components include timed client effects (IngestFeed, Terminal).
Copy, config and nav changes
apps/web/lib/copy/* (home.ts, platform.ts, solutions.ts, developers.ts, company.ts), apps/web/lib/config.ts, apps/web/lib/nav.ts
Refactored and updated marketing/copy data structures (home, platform, solutions, developers, company), adjusted markdown generators, updated site metadata description, and converted nav typing (explicit types, removed as const for nav).
Miscellaneous small edits
apps/web/components/blog/PostCard.tsx, apps/web/contexts/ThemeContext.tsx, apps/web/components/ui/SubscribeForm.tsx, apps/web/components/layout/Header.tsx, various small files
Minor styling/content adjustments (tag pill color, theme provider default to dark, CTA style updates, small component logic fixes).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐇 I nibble copy and stitch a thread,
Five tiny notes for new trials ahead.
A welcome wink, a nudge, a techy clue —
From burrowed drafts these messages flew.
Hop forward, inbox — happy trails to you! ✨📬

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add free trial email drip sequence templates' accurately and concisely describes the main change: adding email templates for a free trial drip sequence to content/email/.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/trial-email-sequence

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@content/email/developer-path.md`:
- Around line 4-6: Update the metadata in content/email/developer-path.md to
match content/email/sequence-overview.md by changing the Trigger from "Day 5 of
trial" to "Day 8 of trial" and the Sequence from "3 of N" to "4 of N" so the
Developer path email aligns with the sequence overview; verify the header lines
that contain the Trigger and Sequence text are updated and consistent with
sequence-overview.md.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 26a80efe-24bf-4f9e-9db5-fde9d46fb731

📥 Commits

Reviewing files that changed from the base of the PR and between e7c1514 and cd87c62.

📒 Files selected for processing (6)
  • AGENTS.md
  • content/email/developer-path.md
  • content/email/free-trial-welcome.md
  • content/email/getting-started.md
  • content/email/personalized-followup.md
  • content/email/sequence-overview.md

Comment on lines +4 to +6
**Trigger:** Day 5 of trial
**Goal:** Show technical users they can integrate Recoupable into their existing workflow.
**Sequence:** 3 of N (see `sequence-overview.md`)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix schedule metadata mismatch with sequence overview.

Line 4 and Line 6 conflict with content/email/sequence-overview.md (Developer path is Day 8, email #4 there). Keeping this as Day 5 / #3 will create sequencing errors when automation is implemented.

Proposed metadata fix
-**Trigger:** Day 5 of trial
+**Trigger:** Day 8 of trial
...
-**Sequence:** 3 of N (see `sequence-overview.md`)
+**Sequence:** 4 of N (see `sequence-overview.md`)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
**Trigger:** Day 5 of trial
**Goal:** Show technical users they can integrate Recoupable into their existing workflow.
**Sequence:** 3 of N (see `sequence-overview.md`)
**Trigger:** Day 8 of trial
**Goal:** Show technical users they can integrate Recoupable into their existing workflow.
**Sequence:** 4 of N (see `sequence-overview.md`)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@content/email/developer-path.md` around lines 4 - 6, Update the metadata in
content/email/developer-path.md to match content/email/sequence-overview.md by
changing the Trigger from "Day 5 of trial" to "Day 8 of trial" and the Sequence
from "3 of N" to "4 of N" so the Developer path email aligns with the sequence
overview; verify the header lines that contain the Trigger and Sequence text are
updated and consistent with sequence-overview.md.

…nd swipe files

- Overhauled copy across home, platform, solutions, developers, about, and records pages
- Added 5 homepage design variations (A-E) for exploration
- New home components: AgentChat, IngestFeed, Marquee, StatusBar, SystemDiagram, Terminal, VisionOverlay
- Added website copy bank and brand swipe files with moodboard screenshots
- Full UX audit with screenshots, findings, critique, and prioritized improvements
- Updated nav structure, theme context, globals.css, and layout config

Made-with: Cursor
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Due to the large number of review comments, Critical severity comments were prioritized as inline comments.

🟠 Major comments (26)
.local/ux-audit/loop3-critique.md-1-42 (1)

1-42: ⚠️ Potential issue | 🟠 Major

This file appears out of scope for the PR objective.

The PR is described as adding free-trial email drip templates, but this file is a homepage UX critique artifact. Please split this into a separate UX/audit PR (or remove it here) to keep review/release scope clean.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.local/ux-audit/loop3-critique.md around lines 1 - 42, The file
.local/ux-audit/loop3-critique.md is out of scope for this PR (which only adds
free-trial email drip templates) and should be removed from this branch or moved
into a separate UX/audit PR; please either delete the file from the commit(s)
touching this branch or create a new branch/PR that contains this UX audit file,
then update this PR to remove that file and adjust the PR description to list
only email-drip related changes so the review scope is correct.
.agents/skills/agent-browser/templates/capture-workflow.sh-14-15 (1)

14-15: ⚠️ Potential issue | 🟠 Major

Guarantee browser cleanup on failure paths.

With set -euo pipefail, a failure before Line 65 exits immediately and leaves the browser session open.

Proposed hardening
 set -euo pipefail
+
+cleanup() {
+  agent-browser close >/dev/null 2>&1 || true
+}
+trap cleanup EXIT
@@
-# Cleanup
-agent-browser close
+# Cleanup handled by trap

Also applies to: 29-31, 65-65

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/skills/agent-browser/templates/capture-workflow.sh around lines 14 -
15, The script currently uses set -euo pipefail but lacks a guaranteed cleanup
for the browser on error/exit; add a cleanup function (e.g., cleanup_browser)
that closes/terminates the browser session/process and set a trap to call it on
EXIT and ERR (trap 'cleanup_browser' EXIT ERR) immediately after set -euo
pipefail and before any browser is launched; ensure any variables for browser
PID or session (the same names used where the browser is started) are referenced
in cleanup_browser and that the trap is removed or replaced only after a clean
shutdown to avoid duplicate handling.
.agents/skills/agent-browser/templates/authenticated-session.sh-25-25 (1)

25-25: ⚠️ Potential issue | 🟠 Major

Close browser before early success exit (and on all exits).

At Line 44, the script exits immediately after snapshotting a restored session, leaving the browser session open.

Proposed fix
 set -euo pipefail
+
+cleanup() {
+  agent-browser close >/dev/null 2>&1 || true
+}
+trap cleanup EXIT
@@
         if [[ "$CURRENT_URL" != *"login"* ]] && [[ "$CURRENT_URL" != *"signin"* ]]; then
             echo "Session restored successfully"
             agent-browser snapshot -i
             exit 0
         fi
@@
-agent-browser close
 exit 0

Also applies to: 41-45, 73-74

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/skills/agent-browser/templates/authenticated-session.sh at line 25,
The script exits early after snapshotting a restored session without closing the
browser; add a cleanup routine and trap to ensure the browser is closed on all
exits. Implement a cleanup function (e.g., cleanup or close_browser) that checks
for and terminates the browser/process used by the session, register it with
trap 'cleanup EXIT' near the top (after set -euo pipefail), and replace
immediate exits after snapshot/restore (the early success exit around the
"snapshotting a restored session" logic and similar exits at lines 41-45 and
73-74) with calls that invoke the cleanup (or simply let the trap handle it by
returning/exit after performing any success logging), ensuring the browser is
always closed before the script exits.
.agents/skills/agent-browser/templates/form-automation.sh-14-15 (1)

14-15: ⚠️ Potential issue | 🟠 Major

Add exit trap so failed runs don’t leave sessions open.

If any command fails before Line 61, the script exits without closing the browser.

Proposed fix
 set -euo pipefail
+
+cleanup() {
+  agent-browser close >/dev/null 2>&1 || true
+}
+trap cleanup EXIT
@@
-# Cleanup
-agent-browser close
+# Cleanup handled by trap

Also applies to: 21-23, 61-61

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/skills/agent-browser/templates/form-automation.sh around lines 14 -
15, The script currently exits on error (set -euo pipefail) but never closes the
browser if an error occurs; add a cleanup function that performs the same
browser/session teardown currently done at the end of the script (close the
browser, kill any background jobs or temp files) and install an EXIT/ERR trap
(e.g., trap cleanup EXIT or trap 'cleanup' ERR EXIT) near the top after set -euo
pipefail so the cleanup runs on normal exit and on failures; ensure the
end-of-script teardown is replaced by or delegates to this cleanup function so
teardown logic is not duplicated (reference the teardown commands currently
executed at the script end and wrap them in cleanup).
.agents/skills/agent-browser/references/authentication.md-65-70 (1)

65-70: ⚠️ Potential issue | 🟠 Major

Replace --session-name with --session in all authentication.md examples.

The canonical documentation (commands.md and session-management.md) consistently use --session, but authentication.md incorrectly uses --session-name across multiple examples (lines 68, 105, 110, 117). This flag name mismatch will cause all shown commands to fail.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/skills/agent-browser/references/authentication.md around lines 65 -
70, Replace every instance of the incorrect flag `--session-name` with the
canonical `--session` in the authentication.md examples (e.g., where the example
command uses `agent-browser --session-name myapp state load ./my-auth.json`),
ensuring all sample commands that mention `--session-name` at lines referenced
(around the examples) are updated so they match the canonical commands in
commands.md and session-management.md; verify any surrounding text and code
blocks reflect the new flag name and run a quick copy/paste test of one example
to confirm the command succeeds.
apps/web/components/layout/ViewModeBar.tsx-11-12 (1)

11-12: ⚠️ Potential issue | 🟠 Major

Hiding the toggle makes machine mode unreachable from the UI.

className="hidden" keeps the component mounted but removes all user access to setView("machine"), so the machine-view path is effectively disabled for end users.

Proposed fix
-    <div className="hidden">
-      <HumanMachineToggle />
-    </div>
+    <div className="fixed bottom-0 left-0 right-0 z-40 flex justify-center pb-6 pointer-events-none">
+      <div className="pointer-events-auto">
+        <HumanMachineToggle />
+      </div>
+    </div>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/components/layout/ViewModeBar.tsx` around lines 11 - 12, The
HumanMachineToggle is hidden via className="hidden", which prevents users from
ever invoking setView("machine"); remove the hard hide and instead conditionally
render or style the toggle so it remains reachable (e.g., remove the "hidden"
class on the <div> wrapping <HumanMachineToggle /> or replace it with a
responsive/permission-based condition), ensuring HumanMachineToggle remains
mounted and keyboard/ARIA accessible so setView("machine") can be triggered by
users.
apps/web/app/designs/d/page.tsx-10-20 (1)

10-20: ⚠️ Potential issue | 🟠 Major

This full-screen mock still leaves the shared chrome in the tab order.

RootLayout keeps rendering Header, Footer, and ViewModeBar around every page in apps/web/app/layout.tsx Lines 84-93. Because this route is only a fixed layer inside <main>, keyboard users can still tab to hidden controls behind the mock. Use a route-specific layout without the shared chrome, or render this page in normal document flow instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/designs/d/page.tsx` around lines 10 - 20, The full-screen mock
in page.tsx uses a fixed-position overlay which leaves the app chrome (Header,
Footer, ViewModeBar rendered by RootLayout) in the tab order; update this route
so those shared controls are not tabbable by either creating a route-specific
layout that omits Header/Footer/ViewModeBar (add a local layout.tsx for this
route that renders only the page content) or by changing the mock in page.tsx to
render in normal document flow (remove position: "fixed"/inset/zIndex layering
and ensure it becomes a regular child of <main>) so keyboard users cannot tab to
hidden controls behind the mock.
apps/web/app/designs/a/page.tsx-10-21 (1)

10-21: ⚠️ Potential issue | 🟠 Major

This full-screen mock still leaves the shared chrome in the tab order.

RootLayout keeps rendering Header, Footer, and ViewModeBar around every page in apps/web/app/layout.tsx Lines 84-93. Because this route is only a fixed layer inside <main>, keyboard users can still tab to hidden controls behind the mock. Use a route-specific layout without the shared chrome, or render this page in normal document flow instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/designs/a/page.tsx` around lines 10 - 21, The page currently
uses a full-screen fixed overlay inside the global RootLayout, so shared chrome
components (Header, Footer, ViewModeBar) remain in the tab order; to fix, either
(A) create a route-specific layout component that replaces RootLayout for this
route (so Header/Footer/ViewModeBar are not rendered) or (B) avoid position:
"fixed"/inset: 0 and render the mock in normal document flow so hidden chrome is
not tabbable; locate this change in apps/web/app/designs/a/page.tsx and adjust
the layout usage or the style accordingly, ensuring focusable/shared controls
from RootLayout are not reachable while the mock is active.
content/brand/website-copy-bank.md-154-154 (1)

154-154: ⚠️ Potential issue | 🟠 Major

Remove or anonymize personal email identifiers in repository copy docs.

Publishing a direct email-style identifier here introduces avoidable privacy/compliance risk; prefer role-based or anonymized wording.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@content/brand/website-copy-bank.md` at line 154, Replace the personal
email-style identifier "Stephanie@ONErpm: 175 days of daily use across 9 months
| Power user at a major distributor |" with an anonymized or role-based string
(e.g., "Stephanie — power user at a major distributor" or "Power user at a major
distributor: 175 days of daily use over 9 months"); in other words, remove the
email-like token "Stephanie@ONErpm" from the copy in the line containing that
exact text and leave only a non-identifying name or role-based descriptor.
apps/web/app/designs/b/page.tsx-83-87 (1)

83-87: ⚠️ Potential issue | 🟠 Major

Navigation labels are non-functional interactive text.

These items present as clickable nav but are plain spans, which creates an accessibility and usability gap. Use semantic links or non-interactive styling.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/designs/b/page.tsx` around lines 83 - 87, The nav items rendered
as plain <span> elements ("PLATFORM", "SOLUTIONS", "DEVELOPERS", "COMPANY") are
styled like links but are not interactive or accessible; replace each <span>
with a semantic interactive element (e.g., <a> or your router's <Link>
component) inside the same container in page.tsx, provide proper hrefs or route
props, ensure keyboard focusability and appropriate ARIA attributes
(aria-current or role="link" only if needed), and remove pointer-only styling so
visual and semantic behavior match.
apps/web/app/designs/e/page.tsx-204-220 (1)

204-220: ⚠️ Potential issue | 🟠 Major

“Watch Demo” currently routes to the same destination as “Start Free.”

Both CTAs point to https://chat.recoupable.com, so users selecting “Watch Demo” won’t get demo intent fulfillment.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/designs/e/page.tsx` around lines 204 - 220, The "Watch Demo"
Link in apps/web/app/designs/e/page.tsx currently uses
href="https://chat.recoupable.com" (same as "Start Free"); update the Link whose
children text is "Watch Demo" to point to the demo-specific destination (for
example replace href with the demo URL or route your product uses, e.g. "/demo"
or "https://recoupable.com/demo") so the CTA fulfills demo intent instead of
routing to the chat page.
.local/ux-audit/teardown-notes.md-1-43 (1)

1-43: ⚠️ Potential issue | 🟠 Major

PR scope drift: this local teardown doc is unrelated to the stated objective.

This file looks like internal UX notes and does not align with the free-trial email sequence scope. Please move it to a separate PR (or keep it out of tracked repo content) to keep review/release risk low.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.local/ux-audit/teardown-notes.md around lines 1 - 43, The file titled
"Teardown Rebuild Notes" (the local UX audit markdown with headings like "What
Just Happened" and "Initialize your workspace.") is out-of-scope for this PR;
remove it from the current changes by either moving the file to a separate
branch/PR or untracking it from the repo (keep your local copy outside the
tracked tree or add to local ignore), then update this PR to exclude the
.local/ux-audit/teardown-notes.md content so only free-trial email sequence
changes remain.
apps/web/app/designs/b/page.tsx-69-177 (1)

69-177: 🛠️ Refactor suggestion | 🟠 Major

Please source marketing copy/brand values from shared copy/config modules.

Hardcoded strings here will drift from the rest of the site and bypass your established content source-of-truth flow.

Based on learnings: Applies to {app,components,lib}/**/*.{ts,tsx} : Edit brand values and page copy only in lib/config.ts and lib/copy/ respectively—never hardcode brand values in components.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/designs/b/page.tsx` around lines 69 - 177, The hero and nav in
page.tsx contain hardcoded brand/copy strings (e.g., "Recoupable", nav labels,
the category span "AI-NATIVE INFRASTRUCTURE", the h1/subheader text, and CTA
Link texts) — replace these literals with imports from your canonical sources
(lib/config.ts for brand values and lib/copy/* for page copy) and use the
imported values inside the nav, headline, subheader, and CTA Link components
(e.g., where Link, h1, p, and the nav spans are rendered) so all marketing copy
comes from the shared config/copy modules rather than inline strings.
apps/web/app/designs/e/page.tsx-104-220 (1)

104-220: 🛠️ Refactor suggestion | 🟠 Major

Move hardcoded page copy/brand text into centralized copy/config.

This route hardcodes brand and messaging strings directly in the component instead of sourcing from lib/copy and config, which will make copy governance and consistency harder.

Based on learnings: Applies to {app,components,lib}/**/*.{ts,tsx} : Edit brand values and page copy only in lib/config.ts and lib/copy/ respectively—never hardcode brand values in components.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/designs/e/page.tsx` around lines 104 - 220, This component
hardcodes brand and page copy (e.g., the "Recoupable" span, headline words
inside the h1 spans like "Your", "label.", "Run by", "agents.", the paragraph
copy and CTA texts "Start Free"/"Watch Demo") instead of using centralized
copy/config; update the component to import the brand values from lib/config.ts
and the page strings from lib/copy (e.g., pageHome.titleParts, pageHome.lede,
ctas.startFree, ctas.watchDemo), replace all hardcoded literals in the
span/h1/p/Link elements with those imported constants, and ensure exports in
lib/config.ts and lib/copy/* are added/updated so components (like the one
containing the h1 and Link usages) reference only the centralized values.
apps/web/app/designs/c/page.tsx-47-131 (1)

47-131: 🛠️ Refactor suggestion | 🟠 Major

Centralize copy/brand strings instead of hardcoding inside the page component.

Most messaging and brand text here should be pulled from lib/copy/config to stay consistent and maintainable across pages.

Based on learnings: Applies to {app,components,lib}/**/*.{ts,tsx} : Edit brand values and page copy only in lib/config.ts and lib/copy/ respectively—never hardcode brand values in components.

Also applies to: 175-259

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/designs/c/page.tsx` around lines 47 - 131, This component
hardcodes brand and copy strings (e.g., "RECOUPABLE", "SYSTEM ACTIVE", the H1
lines "YOUR LABEL. RUN BY AGENTS.", the paragraph copy, the Link href and label
"INITIALIZE SYSTEM") — move these literals into the shared copy/config modules
(lib/copy/* and lib/config.ts) and import them into the page; update the JSX
(including the status span, headline h1 text, paragraph <p>, and the Link
href/children) to reference the imported constants instead of inline strings so
all brand/copy values are maintained centrally.
apps/web/app/designs/c/page.tsx-83-87 (1)

83-87: ⚠️ Potential issue | 🟠 Major

Top-nav items look interactive but are not keyboard-accessible controls.

These span elements use pointer cursors without actual navigation/action semantics, which blocks keyboard users.

Suggested fix
-            <span style={{ cursor: "pointer" }}>PLATFORM</span>
-            <span style={{ cursor: "pointer" }}>SOLUTIONS</span>
-            <span style={{ cursor: "pointer" }}>DEVELOPERS</span>
-            <span style={{ cursor: "pointer" }}>COMPANY</span>
+            <Link href="/platform" style={{ textDecoration: "none", color: "inherit" }}>PLATFORM</Link>
+            <Link href="/solutions" style={{ textDecoration: "none", color: "inherit" }}>SOLUTIONS</Link>
+            <Link href="/developers" style={{ textDecoration: "none", color: "inherit" }}>DEVELOPERS</Link>
+            <Link href="/company" style={{ textDecoration: "none", color: "inherit" }}>COMPANY</Link>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/designs/c/page.tsx` around lines 83 - 87, Top-nav text nodes
currently rendered as non-interactive <span> elements with pointer cursors are
not keyboard-accessible; update the elements in page.tsx (the top-nav spans
rendering "YOUR LABEL."/"RUN BY" etc.) to be semantic interactive
controls—replace each interactive-looking <span> with an <a> (if it navigates)
or a <button> (if it performs an action), give them appropriate href or onClick
handlers, add an accessible name via aria-label or visible text, ensure they are
focusable (no tabIndex="-1"), and remove pointer styles from non-interactive
spans; if you must keep them non-interactive, remove the pointer cursor and any
onclick handlers and add role="presentation".
apps/web/app/designs/b/page.tsx-6-8 (1)

6-8: ⚠️ Potential issue | 🟠 Major

Font loading should use Next.js font APIs, not inline CSS import in JSX.

Using runtime @import in the component is a performance/maintainability regression. The root layout demonstrates the correct pattern with next/font/google, which provides optimized font delivery, prevents layout shift, and enables preloading. Inline @import blocks rendering and bypasses Next.js optimizations entirely.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/designs/b/page.tsx` around lines 6 - 8, Remove the inline
<style> block that uses `@import` in page.tsx and switch to Next.js font APIs:
import the Playfair Display, Space Mono and Inter families via next/font/google
in this module (or a shared fonts module) and apply the generated className(s)
to the page root/container instead of injecting CSS at render time; ensure you
mirror the pattern used in the root layout (preloading/variable/className from
next/font/google) so fonts are optimized and avoid using runtime `@import` in the
JSX.
apps/web/app/designs/c/page.tsx-6-8 (1)

6-8: ⚠️ Potential issue | 🟠 Major

Switch to next/font/google for font loading.

Inline @import in rendered markup causes runtime CSS loading. Use next/font/google at the page or layout level instead—Next.js 16 optimizes font delivery at build time. This pattern is already established in layout.tsx and should be applied consistently here.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/designs/c/page.tsx` around lines 6 - 8, Remove the inline
<style> block that contains the `@import` and instead load fonts with
next/font/google: import the Inter and Space_Mono (Space Mono) families via
next/font/google, create font instances (e.g., const inter = Inter({...}), const
spaceMono = Space_Mono({...})), and apply the generated className(s) to the
page’s root element (or reuse the layout.tsx font exports) so font loading
happens at build time; specifically replace the <style>{`@import...`}</style> in
page.tsx with next/font/google usage and remove any runtime CSS import.
apps/web/app/designs/e/page.tsx-6-8 (1)

6-8: ⚠️ Potential issue | 🟠 Major

Use Next.js font loading instead of runtime @import in component markup.

Embedding Google Fonts via inline <style> here is fragile and slower than next/font/google for this route.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/designs/e/page.tsx` around lines 6 - 8, The component currently
injects Google Fonts via an inline <style> with `@import`; replace this with
Next.js font loading by importing Cormorant_Garamond and Inter from
next/font/google (or use next/font's API), configure the weights/italics you
need, and apply the returned font className or variable to the root element
(e.g., the component's top-level div or html/body) instead of rendering the
<style> block; remove the inline <style> from page.tsx and ensure any existing
references to those fonts use the Next font exports (e.g., font.className or
font.variable) so fonts are loaded at build time and optimized by Next.js.
apps/web/app/solutions/page.tsx-53-57 (1)

53-57: ⚠️ Potential issue | 🟠 Major

This hero placeholder doesn't match the audiences below.

The page targets artists, labels, distributors, and catalog owners, but the visible label says ARTIST / LABEL / DEVELOPER. That drops two real segments and introduces one the page doesn't actually cover.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/solutions/page.tsx` around lines 53 - 57, The hero placeholder
text in the span inside apps/web/app/solutions/page.tsx ("ARTIST / LABEL /
DEVELOPER") is incorrect for the page's audiences; update the span's text
content (the <span> with className "text-[var(--muted-foreground)] text-sm
font-mono") to accurately reflect the target groups shown below (e.g., "Artists
/ Labels / Distributors / Catalog Owners" or a similar concise set) so the hero
matches the page audience.
apps/web/app/platform/page.tsx-85-90 (1)

85-90: ⚠️ Potential issue | 🟠 Major

Visible placeholder panels shouldn't ship on the live platform page.

The PLATFORM SCREENSHOT and CONTENT PIPELINE blocks read as unfinished mocks, which undercuts the credibility this redesign is trying to build. Render these only when real media exists, or omit them for now.

Also applies to: 129-132

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/platform/page.tsx` around lines 85 - 90, The placeholder panels
("PLATFORM SCREENSHOT" and "CONTENT PIPELINE") should not render
unconditionally; update the JSX in the page component so the screenshot block
(the div containing the span "PLATFORM SCREENSHOT") and the content-pipeline
block (the block around lines ~129-132) are only rendered when actual media
exists (e.g., check props/state like platformScreenshot or
contentPipelineMedia). Replace the static placeholder markup with a conditional
render such as if (platformScreenshot) { /* render image/video container */ }
else { null } (same for contentPipelineMedia), or remove the placeholder blocks
entirely if no media source will ever be provided; ensure you reference and use
the existing variables/props in this component rather than leaving the literal
span visible.
apps/web/app/company/recoupable-records/page.tsx-43-45 (1)

43-45: ⚠️ Potential issue | 🟠 Major

Don't ship proof sections with visible placeholder artwork.

On a page meant to prove the output is real, literal GATSBY GRACE and 22 VIDEOS — CONTENT OUTPUT placeholders make the proof feel unfinished instead of concrete. Use real media or remove these panels until assets are ready.

Also applies to: 65-67

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/company/recoupable-records/page.tsx` around lines 43 - 45, The
visible placeholder artwork and copy (the div with class "relative aspect-square
lg:aspect-auto bg-[var(--muted)] ..." and the span containing "GATSBY GRACE",
plus the similar block at the 65-67 region) must not be shipped as literal
placeholders; either replace these blocks with real media components (e.g., an
Image/Video component or a proper media card) or remove/conditionally render
them until assets are available—if you need a placeholder keep it non-revealing
(skeleton loader or empty state) rather than hardcoded text. Ensure you update
the JSX in page.tsx where those spans and surrounding divs are defined (and the
matching block at lines ~65-67) so the UI shows real content or a neutral loader
instead of the "GATSBY GRACE"/"22 VIDEOS — CONTENT OUTPUT" placeholders.
apps/web/components/home/VisionOverlay.tsx-108-123 (1)

108-123: ⚠️ Potential issue | 🟠 Major

This overlay shouldn't depend on theme text tokens for readability.

The background is always near-black, but the terminal readout uses var(--foreground) and var(--muted-foreground). In light theme those tokens are dark, so this copy becomes low-contrast or unreadable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/components/home/VisionOverlay.tsx` around lines 108 - 123, The
overlay uses theme tokens (e.g., text-[var(--foreground)] and
text-[var(--muted-foreground)] inside the VisionOverlay component) which can
become low-contrast on light themes; change the readout to use fixed
high-contrast colors or context-aware utility classes (for example replace
text-[var(--foreground)] / text-[var(--muted-foreground)] on elements with
explicit light-on-dark colors or a dark-theme-only token) so the terminal
readout remains readable against the always near-black background; update the
span and p elements with classes like "vision-readout-line" and the inline span
wrappers (e.g., the AESTHETIC_SCORE and GENRE_PROB spans) to use the new color
classes.
apps/web/app/platform/page.tsx-149-165 (1)

149-165: ⚠️ Potential issue | 🟠 Major

Don't use --foreground as the background token for this callout.

--foreground is the text token. In a themed app this section can collapse into light-on-light text (bg-[var(--foreground)] + text-white) as soon as the foreground token flips for dark mode.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/platform/page.tsx` around lines 149 - 165, The section is using
the text token as a background (className "bg-[var(--foreground)]") which will
break theming; change the background token to a proper background/callout token
(for example replace "bg-[var(--foreground)]" with "bg-[var(--background)]" or
your design system's callout/card token like "bg-[var(--card)]" or
"bg-[var(--muted)]") in the section element that renders c.notSection (the
<section className="bg-[var(--foreground)] text-white py-16 sm:py-20">) so the
background uses a background-specific CSS variable instead of --foreground.
apps/web/app/company/about/page.tsx-40-42 (1)

40-42: ⚠️ Potential issue | 🟠 Major

Make the founder media slot responsive before shipping it.

With px-6 on the page container, a fixed w-[280px] shrink-0 box overflows 320px screens, and rendering FOUNDER PHOTO as literal UI makes the section feel unfinished even when it fits.

📱 Suggested change
-          <div className="shrink-0 w-[280px] h-[280px] rounded-2xl bg-[var(--muted)] border border-[var(--border)] flex items-center justify-center">
+          <div className="shrink-0 w-full max-w-[280px] aspect-square rounded-2xl bg-[var(--muted)] border border-[var(--border)] flex items-center justify-center">
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/company/about/page.tsx` around lines 40 - 42, The fixed media
box (div with class "shrink-0 w-[280px] h-[280px] rounded-2xl ...") overflows
small viewports and shows an unfinished literal "FOUNDER PHOTO"; change it to a
responsive slot by replacing the fixed sizing with responsive utilities such as
"w-full max-w-[280px] sm:w-[280px] aspect-square" (or "h-auto aspect-square
max-w-[280px]") and remove "shrink-0", and render a proper placeholder element
(skeleton/icon or next/Image with object-cover and alt text) instead of the
plain span; update the container classes in apps/web/app/company/about/page.tsx
so the media scales on narrow screens and the placeholder is accessible
(aria-hidden/alt as appropriate).
apps/web/app/page.tsx-54-56 (1)

54-56: ⚠️ Potential issue | 🟠 Major

Use a theme token for the hero subheader color.

Line 56 hardcodes an off-white RGBA, so this copy loses contrast when [data-theme="light"] is active. Bind it to a theme token instead of a fixed dark-theme color.

🎨 Suggested fix
-          <p
-            className="text-editorial text-xl sm:text-2xl md:text-3xl mb-14 max-w-2xl leading-relaxed"
-            style={{ color: "rgba(240, 235, 227, 0.6)" }}
-          >
+          <p className="text-editorial text-xl sm:text-2xl md:text-3xl mb-14 max-w-2xl leading-relaxed text-(--muted-foreground)">
             {c.hero.subheader}
           </p>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/page.tsx` around lines 54 - 56, The hero subheader currently
hardcodes color via style={{ color: "rgba(240, 235, 227, 0.6)" }} in the <p>
element in apps/web/app/page.tsx; remove that inline RGBA and bind the text
color to your theme token instead (for example replace with a CSS variable like
color: var(--muted-foreground) or a tailwind/theme token class such as
text-muted or text-foreground-subtle), and if the token/utility doesn't exist
add it to your global styles or theme tokens so it responds to
[data-theme="light"] vs dark; update the <p> element in page.tsx to use the
token/utility and adjust global CSS/theme config accordingly.
🟡 Minor comments (14)
apps/web/components/home/AgentChat.tsx-8-35 (1)

8-35: ⚠️ Potential issue | 🟡 Minor

Respect prefers-reduced-motion for the fade sequence.

Line 21 applies animation to all staged messages, but there’s no reduced-motion fallback. Add a media query so users with motion sensitivity don’t get forced transitions.

Suggested patch
       <style>{`
         `@keyframes` agent-chat-fade-in {
           from {
             opacity: 0;
             transform: translateY(6px);
           }
           to {
             opacity: 1;
             transform: translateY(0);
           }
         }
         .agent-chat-fade {
           opacity: 0;
           animation: agent-chat-fade-in 0.5s ease-out forwards;
         }
+        `@media` (prefers-reduced-motion: reduce) {
+          .agent-chat-fade {
+            opacity: 1;
+            transform: none;
+            animation: none;
+          }
+        }
         .agent-chat-delay-1 {
           animation-delay: 0.15s;
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/components/home/AgentChat.tsx` around lines 8 - 35, The CSS
animation in AgentChat.tsx applies to .agent-chat-fade and the delay classes but
doesn't respect users' prefers-reduced-motion setting; add a media query `@media`
(prefers-reduced-motion: reduce) wrapping rules that disable the animation for
.agent-chat-fade and the .agent-chat-delay-* classes (set animation: none;
animation-delay: 0; and ensure opacity: 1 and transform: none) so staged
messages render immediately without transitions.
.agents/skills/agent-browser/references/authentication.md-280-283 (1)

280-283: ⚠️ Potential issue | 🟡 Minor

.gitignore example doesn’t match the default state filename.

*.auth-state.json won’t match auth-state.json used elsewhere in this doc.

Suggested correction
-echo "*.auth-state.json" >> .gitignore
+echo "auth-state.json" >> .gitignore
+echo "*.auth-state.json" >> .gitignore
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/skills/agent-browser/references/authentication.md around lines 280 -
283, The .gitignore example currently uses the pattern "*.auth-state.json" which
does not match the plain filename auth-state.json referenced elsewhere; update
the .gitignore example to include the actual state filename (for example
auth-state.json) or a pattern that matches it (e.g., *auth-state.json or
auth-state.json) so the state file is properly ignored; locate the example
string "*.auth-state.json" in the doc and replace it with the corrected pattern
or filename.
.agents/skills/agent-browser/references/proxy-support.md-3-3 (1)

3-3: ⚠️ Potential issue | 🟡 Minor

Use hyphenation for the compound modifier.

At Line 3, “rate limiting avoidance” reads cleaner as “rate-limiting avoidance.”

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/skills/agent-browser/references/proxy-support.md at line 3, Change
the phrase "rate limiting avoidance" to use hyphenation as "rate-limiting
avoidance" in the document; locate the occurrence of the exact substring "rate
limiting avoidance" in the text (e.g., within the sentence starting "Proxy
configuration for ...") and update it to "rate-limiting avoidance" to correct
the compound modifier.
.agents/skills/agent-browser/references/snapshot-refs.md-20-27 (1)

20-27: ⚠️ Potential issue | 🟡 Minor

Add fenced code languages to satisfy markdown lint.

These code fences are missing language identifiers (text, bash, etc.), which triggers MD040.

Suggested fix pattern
-```
+```text
 Full DOM/HTML → AI parses → CSS selector → Action (~3000-5000 tokens)

Apply the same pattern to the other unlabeled fences.
</details>


Also applies to: 41-61, 140-163

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @.agents/skills/agent-browser/references/snapshot-refs.md around lines 20 -
27, The markdown fences in snapshot-refs.md are missing language identifiers and
trigger MD040; update each unlabeled triple-backtick block (e.g., the blocks
containing "Full DOM/HTML → AI parses → CSS selector → Action (~3000-5000
tokens)" and "Compact snapshot → @refs assigned → Direct interaction (~200-400
tokens)") to include a language tag like "text" (and apply the same change to
the other unlabeled fences referenced around lines 41-61 and 140-163) so the
linter is satisfied.


</details>

</blockquote></details>
<details>
<summary>swipe/swipe-files/design-analysis.md-1-3 (1)</summary><blockquote>

`1-3`: _⚠️ Potential issue_ | _🟡 Minor_

**Move this note into an approved swipe location.**

`swipe/swipe-files/` isn't one of the allowed swipe buckets, and this document reads more like synthesized design guidance than a raw reference item. Put it under an approved bucket such as `swipe/designs/` with a more specific filename, or move it out of `swipe/` entirely if it's meant to be an internal analysis artifact.



As per coding guidelines "Store reference swipe file items in `swipe/` subdirectories (copy/, designs/, competitors/, complaints/, trends/) with descriptive filenames" and "Use descriptive filenames for swipe file items."

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @swipe/swipe-files/design-analysis.md around lines 1 - 3, The file
"swipe/swipe-files/design-analysis.md" is in a disallowed bucket and reads like
synthesized design guidance rather than a raw swipe; move it into an approved
swipe subdirectory (e.g., place the file under "swipe/designs/" or remove it
from "swipe/" if it’s internal), rename it to a descriptive filename reflecting
its purpose (for example
"swipe/designs/recoupable-brand-guidelines-analysis.md"), and update any
references or links to the document; ensure the file content and name match the
coding guidelines for swipe subdirectories and descriptive filenames.


</details>

</blockquote></details>
<details>
<summary>apps/web/components/home/Marquee.tsx-3-12 (1)</summary><blockquote>

`3-12`: _⚠️ Potential issue_ | _🟡 Minor_

**Move the ticker copy into `lib/copy/`.**

These labels are homepage copy, so hardcoding them here will make the marketing text drift as soon as another section or experiment wants to reuse the same concepts.



Based on learnings "Edit brand values and page copy only in `lib/config.ts` and `lib/copy/` respectively—never hardcode brand values in components."

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @apps/web/components/home/Marquee.tsx around lines 3 - 12, The KEYWORDS array
in Marquee.tsx is hardcoded; move this marketing copy into lib/copy (e.g.,
export as HOMEPAGE_TICKER or MARQUEE_KEYWORDS) and replace the local const
KEYWORDS with an import from that module in Marquee.tsx; ensure the exported
value keeps the same shape/readonly typing (as const) so existing usage in the
Marquee component continues to work and update any nearby references or tests
that import/expect KEYWORDS to use the new exported name.


</details>

</blockquote></details>
<details>
<summary>apps/web/components/home/Marquee.tsx-36-43 (1)</summary><blockquote>

`36-43`: _⚠️ Potential issue_ | _🟡 Minor_

**Don't hide the only capability list from assistive tech.**

`aria-hidden="true"` suppresses this entire message for screen readers. If the marquee is decorative, add a visually hidden static equivalent; otherwise expose the semantic content and hide only the duplicated animated row.



<details>
<summary>Suggested fix</summary>

```diff
 export function Marquee() {
   return (
-    <div
-      className="w-full overflow-hidden border-y border-(--border) bg-(--muted) py-3 text-(--brand)"
-      aria-hidden="true"
-    >
-      <div className="flex w-max animate-marquee">
-        <MarqueeSequence id="a" />
-        <MarqueeSequence id="b" />
-      </div>
-    </div>
+    <>
+      <p className="sr-only">{KEYWORDS.join(", ")}</p>
+      <div
+        className="w-full overflow-hidden border-y border-(--border) bg-(--muted) py-3 text-(--brand)"
+        aria-hidden="true"
+      >
+        <div className="flex w-max animate-marquee">
+          <MarqueeSequence id="a" />
+          <MarqueeSequence id="b" />
+        </div>
+      </div>
+    </>
   );
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/components/home/Marquee.tsx` around lines 36 - 43, The marquee
container currently uses aria-hidden="true" which hides the only capability list
from assistive tech; remove aria-hidden from the outer div and instead hide only
the duplicated/animated content (e.g., set aria-hidden on the animated row or
the duplicate MarqueeSequence with id="b"), and add a non-animated, visually
hidden static equivalent (a screen-reader-only element) inside Marquee (or
alongside MarqueeSequence id="a") that exposes the same semantic list to
assistive technologies so screen readers get one accessible copy while the
animation remains decorative.
apps/web/app/designs/a/page.tsx-15-17 (1)

15-17: ⚠️ Potential issue | 🟡 Minor

Move the mock's tokens and copy into the shared sources.

This route hardcodes brand colors, product labels, CTA text, and marketing copy throughout the JSX. Even for design variants, that will drift immediately from lib/config.ts / lib/copy/ and turn simple copy updates into component edits.

Based on learnings "Edit brand values and page copy only in lib/config.ts and lib/copy/ respectively—never hardcode brand values in components."

Also applies to: 38-43, 52-75, 109-165, 183-230

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/designs/a/page.tsx` around lines 15 - 17, This component
currently hardcodes design tokens and copy (e.g., backgroundColor, fontFamily,
color and all product labels/CTA/marketing strings used in the JSX) — extract
those brand colors and token values into lib/config.ts and move all user-facing
copy into lib/copy/, then import them into the page component and replace every
hardcoded value with the corresponding imported constant; specifically replace
inline style keys (backgroundColor, fontFamily, color) with token references
(e.g., theme.background, theme.font, theme.textColor) and replace all labels/CTA
text/marketing strings used in the component with copy keys from lib/copy (e.g.,
copy.heroTitle, copy.ctaText, product names), ensuring the component reads from
these shared modules instead of embedding literals so future edits live in
config/copy only.
apps/web/app/designs/d/page.tsx-15-18 (1)

15-18: ⚠️ Potential issue | 🟡 Minor

Move the mock's tokens and copy into the shared sources.

This route hardcodes brand colors, product labels, CTA text, and workflow copy throughout the JSX. Even for design variants, that will drift immediately from lib/config.ts / lib/copy/ and turn simple copy updates into component edits.

Based on learnings "Edit brand values and page copy only in lib/config.ts and lib/copy/ respectively—never hardcode brand values in components."

Also applies to: 67-75, 183-230, 260-307

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/designs/d/page.tsx` around lines 15 - 18, The page component
currently hardcodes brand tokens and copy (e.g., the inline style object with
background/fontFamily and all CTA text, product labels and workflow copy inside
the JSX) which should be centralized; import the canonical values from
lib/config.ts for brand tokens (colors, fonts, tokens) and from lib/copy/* for
all user-facing strings, then replace the inline literals in the default
exported page component (and any local constants used for variants) with those
imports so copy and theme are driven from the shared sources rather than
hardcoded in the component.
apps/web/components/home/StatusBar.tsx-6-35 (1)

6-35: ⚠️ Potential issue | 🟡 Minor

Move the strip's tokens and copy out of the JSX.

The background/accent colors, version label, and tool-count copy are all hardcoded here. That makes this bar drift from the shared theme/copy sources and forces future product or brand updates into component diffs.

Based on learnings "Edit brand values and page copy only in lib/config.ts and lib/copy/ respectively—never hardcode brand values in components."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/components/home/StatusBar.tsx` around lines 6 - 35, StatusBar.tsx
currently hardcodes brand colors and copy (status dot color, text colors,
version string "V. 2.0.4 // AGENT_CORE", and "40+ MCP TOOLS ACTIVE"); replace
these literals by importing values from the shared theme and copy modules
(lib/config.ts for brand tokens like onlineColor/accentColor/borderColor and
lib/copy/* for strings like statusLabel/versionLabel/toolCountLabel), update the
component to reference those symbols (e.g., StatusBar component uses
config.onlineColor, config.borderToken and copy.statusText, copy.versionText,
copy.toolCountText) and remove inline hex/class literals so the styling uses the
theme tokens and the text uses centralized copy entries; ensure aria-hidden and
className usage stays the same but composed from the imported tokens so future
brand or copy changes live only in lib/config.ts and lib/copy.
apps/web/app/layout.tsx-72-75 (1)

72-75: ⚠️ Potential issue | 🟡 Minor

Guard and validate the pre-paint theme read.

This bootstrap script now writes any stored string straight into data-theme, and a blocked localStorage.getItem() call will abort the script before the attribute is set at all. That leaves first paint out of sync with ThemeContext on stale/corrupt storage and can reintroduce the flash this script is supposed to prevent.

Suggested fix
         <script
           dangerouslySetInnerHTML={{
-            __html: `(function(){var k='recoupable-theme:v1';var s=typeof localStorage!='undefined'&&localStorage.getItem(k);if(!s)s='dark';document.documentElement.setAttribute('data-theme',s);})();`,
+            __html: `(function(){var k='recoupable-theme:v1';var s='dark';try{var stored=typeof localStorage!='undefined'&&localStorage.getItem(k);if(stored==='dark'||stored==='light')s=stored;}catch(e){}document.documentElement.setAttribute('data-theme',s);})();`,
           }}
         />

Based on learnings "When writing or refactoring React/Next.js components, pages, or data fetching, follow Vercel React best practices: no barrel imports, no async waterfalls, minimal RSC payload, safe localStorage usage."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/layout.tsx` around lines 72 - 75, The inline bootstrap script in
layout.tsx currently trusts localStorage.getItem(k) and will abort if
localStorage is unavailable; update the IIFE that defines k =
'recoupable-theme:v1' to wrap localStorage access in a try/catch, validate the
retrieved value against an allowlist (e.g., 'light'|'dark'), default to 'dark'
on any error or invalid value, and always call
document.documentElement.setAttribute('data-theme', chosenValue) so first paint
is never left unset; locate the script block using the exact string/variable k
and the IIFE to apply this change.
.local/ux-audit/audit-findings.md-54-56 (1)

54-56: ⚠️ Potential issue | 🟡 Minor

This developers-page finding is already stale.

It says the developers page has “no icons” and “no code snippets,” but this PR adds both in apps/web/app/developers/page.tsx. Update or narrow the statement so the audit remains trustworthy.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.local/ux-audit/audit-findings.md around lines 54 - 56, Update the "6.
Wall-of-Text Pages" audit statement to remove or narrow the blanket claim that
the developers page has "no icons" and "no code snippets"—the developers page
component now includes icons and code snippets—so edit the sentence under the
"Wall-of-Text Pages" heading to either exclude the developers page from that
example or qualify it (e.g., "most pages" or "except the developers page, which
includes icons and code snippets") to keep the audit accurate and trustworthy;
search for the "Wall-of-Text Pages" heading and the sentence referencing
"Platform, Solutions, Developers, Vision, About, Records" and revise it
accordingly.
apps/web/app/globals.css-142-158 (1)

142-158: ⚠️ Potential issue | 🟡 Minor

Add a reduced-motion fallback for the infinite animations.

animate-marquee, animate-blink, and fade-in-up currently ignore prefers-reduced-motion, so motion-sensitive users still get the full animation layer.

♿ Suggested guard
+@media (prefers-reduced-motion: reduce) {
+  .animate-marquee,
+  .animate-blink,
+  .fade-in-up {
+    animation: none !important;
+    transform: none !important;
+  }
+}

Also applies to: 204-209

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/globals.css` around lines 142 - 158, The infinite animations
(classes animate-marquee, animate-blink and the fade-in-up animation) ignore
users' prefers-reduced-motion. Add a prefers-reduced-motion: reduce media query
that disables these animations by setting animation: none (or
animation-duration: 0s and transition: none) for .animate-marquee,
.animate-blink and .fade-in-up (and any related keyframe-based classes), and
ensure the keyframes remain defined but aren’t applied under the reduced-motion
media query so motion-sensitive users get a static experience.
.local/ux-audit/rebuild-direction.md-47-49 (1)

47-49: ⚠️ Potential issue | 🟡 Minor

Clarify whether #c8ff00 is the only allowed green.

Line 47 approves #c8ff00, but Line 49 says “No green.” That leaves the palette rule self-contradictory for implementers. Narrow the ban to teal/dark greens or explicitly exempt the chosen accent.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.local/ux-audit/rebuild-direction.md around lines 47 - 49, The palette text
is self-contradictory about green: clarify that the Accent electric yellow-green
(`#c8ff00`) is allowed and narrow the prohibition to teal/dark greens by updating
the "No teal. No green. No `#345A5D`." line to something like "No teal or dark
greens (e.g., `#345A5D`); exception: accent `#c8ff00` is allowed" so implementers
know `#c8ff00` is permitted while other greens/teals are disallowed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 872444c8-fcc9-496a-bcff-eec0f87c5306

📥 Commits

Reviewing files that changed from the base of the PR and between cd87c62 and 906dcf2.

⛔ Files ignored due to path filters (35)
  • .local/ux-audit/screenshots/about-desktop-full.png is excluded by !**/*.png
  • .local/ux-audit/screenshots/blog-desktop-full.png is excluded by !**/*.png
  • .local/ux-audit/screenshots/developers-desktop-full.png is excluded by !**/*.png
  • .local/ux-audit/screenshots/home-desktop-full.png is excluded by !**/*.png
  • .local/ux-audit/screenshots/home-mobile-full.png is excluded by !**/*.png
  • .local/ux-audit/screenshots/platform-desktop-full.png is excluded by !**/*.png
  • .local/ux-audit/screenshots/records-desktop-full.png is excluded by !**/*.png
  • .local/ux-audit/screenshots/solutions-desktop-full.png is excluded by !**/*.png
  • .local/ux-audit/screenshots/vision-desktop-full.png is excluded by !**/*.png
  • swipe/swipe-files/Recoupable SMB Sales Deck.pdf is excluded by !**/*.pdf
  • swipe/swipe-files/current-platform.png is excluded by !**/*.png
  • swipe/swipe-files/current-website.png is excluded by !**/*.png
  • swipe/swipe-files/moodboard/Screenshot 2026-03-30 at 3.57.51 PM.png is excluded by !**/*.png
  • swipe/swipe-files/moodboard/Screenshot 2026-03-30 at 3.58.23 PM.png is excluded by !**/*.png
  • swipe/swipe-files/moodboard/Screenshot 2026-03-30 at 3.59.15 PM.png is excluded by !**/*.png
  • swipe/swipe-files/moodboard/Screenshot 2026-03-30 at 3.59.43 PM.png is excluded by !**/*.png
  • swipe/swipe-files/moodboard/Screenshot 2026-03-30 at 4.00.57 PM.png is excluded by !**/*.png
  • swipe/swipe-files/moodboard/Screenshot 2026-03-30 at 4.02.26 PM.png is excluded by !**/*.png
  • swipe/swipe-files/moodboard/Screenshot 2026-03-30 at 4.07.12 PM.png is excluded by !**/*.png
  • swipe/swipe-files/moodboard/Screenshot 2026-03-30 at 4.07.33 PM.png is excluded by !**/*.png
  • swipe/swipe-files/moodboard/Screenshot 2026-03-30 at 4.07.55 PM.png is excluded by !**/*.png
  • swipe/swipe-files/moodboard/Screenshot 2026-03-30 at 4.08.46 PM.png is excluded by !**/*.png
  • swipe/swipe-files/moodboard/Screenshot 2026-03-30 at 4.31.28 PM.png is excluded by !**/*.png
  • swipe/swipe-files/moodboard/Screenshot 2026-03-30 at 4.32.18 PM.png is excluded by !**/*.png
  • swipe/swipe-files/moodboard/Screenshot 2026-03-30 at 4.33.06 PM.png is excluded by !**/*.png
  • swipe/swipe-files/moodboard/Screenshot 2026-03-30 at 4.34.00 PM.png is excluded by !**/*.png
  • swipe/swipe-files/moodboard/Screenshot 2026-03-30 at 4.34.19 PM.png is excluded by !**/*.png
  • swipe/swipe-files/moodboard/Screenshot 2026-03-30 at 4.34.37 PM.png is excluded by !**/*.png
  • swipe/swipe-files/moodboard/Screenshot 2026-03-30 at 4.35.43 PM.png is excluded by !**/*.png
  • swipe/swipe-files/moodboard/Screenshot 2026-03-30 at 4.36.17 PM.png is excluded by !**/*.png
  • swipe/swipe-files/variations/A-current-site.png is excluded by !**/*.png
  • swipe/swipe-files/variations/B-editorial-magazine.png is excluded by !**/*.png
  • swipe/swipe-files/variations/C-split-screen.png is excluded by !**/*.png
  • swipe/swipe-files/variations/D-glass-morphism.png is excluded by !**/*.png
  • swipe/swipe-files/variations/E-night-session.png is excluded by !**/*.png
📒 Files selected for processing (65)
  • .agents/skills/agent-browser/SKILL.md
  • .agents/skills/agent-browser/references/authentication.md
  • .agents/skills/agent-browser/references/commands.md
  • .agents/skills/agent-browser/references/profiling.md
  • .agents/skills/agent-browser/references/proxy-support.md
  • .agents/skills/agent-browser/references/session-management.md
  • .agents/skills/agent-browser/references/snapshot-refs.md
  • .agents/skills/agent-browser/references/video-recording.md
  • .agents/skills/agent-browser/templates/authenticated-session.sh
  • .agents/skills/agent-browser/templates/capture-workflow.sh
  • .agents/skills/agent-browser/templates/form-automation.sh
  • .claude/skills/agent-browser
  • .local/ux-audit/README.md
  • .local/ux-audit/audit-findings.md
  • .local/ux-audit/brutal-critique.md
  • .local/ux-audit/discovery-funnels.md
  • .local/ux-audit/finding-our-own-voice.md
  • .local/ux-audit/flywheel-notes.md
  • .local/ux-audit/improvements-prioritized.md
  • .local/ux-audit/iteration-log.md
  • .local/ux-audit/loop1-critique.md
  • .local/ux-audit/loop3-critique.md
  • .local/ux-audit/page-by-page-notes.md
  • .local/ux-audit/rebuild-direction.md
  • .local/ux-audit/teardown-notes.md
  • .local/ux-audit/user-stories.md
  • apps/web/app/company/about/page.tsx
  • apps/web/app/company/recoupable-records/page.tsx
  • apps/web/app/designs/a/page.tsx
  • apps/web/app/designs/b/page.tsx
  • apps/web/app/designs/c/page.tsx
  • apps/web/app/designs/d/page.tsx
  • apps/web/app/designs/e/page.tsx
  • apps/web/app/developers/page.tsx
  • apps/web/app/globals.css
  • apps/web/app/layout.tsx
  • apps/web/app/page.tsx
  • apps/web/app/platform/page.tsx
  • apps/web/app/solutions/page.tsx
  • apps/web/components/blog/PostCard.tsx
  • apps/web/components/home/AgentChat.tsx
  • apps/web/components/home/IngestFeed.tsx
  • apps/web/components/home/Marquee.tsx
  • apps/web/components/home/StatusBar.tsx
  • apps/web/components/home/SystemDiagram.tsx
  • apps/web/components/home/Terminal.tsx
  • apps/web/components/home/VisionOverlay.tsx
  • apps/web/components/layout/Footer.tsx
  • apps/web/components/layout/Header.tsx
  • apps/web/components/layout/NavDropdown.tsx
  • apps/web/components/layout/ViewModeBar.tsx
  • apps/web/components/ui/FigureLabel.tsx
  • apps/web/components/ui/SubscribeForm.tsx
  • apps/web/contexts/ThemeContext.tsx
  • apps/web/lib/config.ts
  • apps/web/lib/copy/company.ts
  • apps/web/lib/copy/developers.ts
  • apps/web/lib/copy/home.ts
  • apps/web/lib/copy/platform.ts
  • apps/web/lib/copy/solutions.ts
  • apps/web/lib/nav.ts
  • content/brand/website-copy-bank.md
  • skills-lock.json
  • skills/agent-browser
  • swipe/swipe-files/design-analysis.md
✅ Files skipped from review due to trivial changes (21)
  • .claude/skills/agent-browser
  • skills/agent-browser
  • apps/web/components/blog/PostCard.tsx
  • apps/web/components/layout/Footer.tsx
  • .local/ux-audit/README.md
  • skills-lock.json
  • apps/web/components/ui/SubscribeForm.tsx
  • .agents/skills/agent-browser/references/profiling.md
  • .agents/skills/agent-browser/references/session-management.md
  • .agents/skills/agent-browser/references/video-recording.md
  • .local/ux-audit/iteration-log.md
  • apps/web/components/ui/FigureLabel.tsx
  • apps/web/components/layout/Header.tsx
  • .local/ux-audit/improvements-prioritized.md
  • .agents/skills/agent-browser/references/commands.md
  • apps/web/lib/config.ts
  • .local/ux-audit/user-stories.md
  • apps/web/lib/copy/developers.ts
  • apps/web/lib/copy/company.ts
  • .agents/skills/agent-browser/SKILL.md
  • .local/ux-audit/page-by-page-notes.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant